/**
 * Software License, Version 1.0
 * 
 * Copyright 2008 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgment:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgment may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or Granules, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called Granules, 
 * nor may Indiana University or Community Grids Lab or Granules appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 * LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 * WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 * NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 * INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 * INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 * "VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 * LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 * ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 * GENERATED USING SOFTWARE.
 */

package cgl.granules.dataset;

import java.io.IOException;

import cgl.granules.exception.MarshallingException;
import cgl.granules.util.MarshallingUtil;

/**
 * A factory for creating different types of datasets. Also contains various
 * utility methods to access information about the datasets.
 * 
 * @author Shrideep Pallickara
 * 
 */
public class DatasetFactory {
	private static final DatasetFactory instance = new DatasetFactory();

	private MarshallingUtil marshallingUtil = MarshallingUtil.getInstance();

	private DatasetFactory() {

	}

	/**
	 * Retrieve the singleton instance of the dataset factory
	 * 
	 * @return The singleton instance of the factory.
	 */
	public static DatasetFactory getInstance() {
		return instance;
	}

	/**
	 * Retrieves the dataset type information from a stream of bytes.
	 * 
	 * @param datasetBytes
	 *            The byte[] representation of the dataset
	 * @return The dataset <i>type</i>
	 * @throws MarshallingException
	 *             if there are problems with the retrieving information from
	 *             the dataset bytes
	 */
	public int getDatasetType(byte[] datasetBytes) {
		int datasetType = marshallingUtil.getInt(datasetBytes, 0);

		return datasetType;
	}

	/**
	 * Reconstructs the dataset from a set of bytes
	 * 
	 * @param datasetBytes
	 *            The byte[] representation of the dataset.
	 * @return The reconstructed Dataset.
	 * @throws DatasetException
	 *             If there are problems in reconstructing the dataset
	 */
	public Dataset getDataset(byte[] datasetBytes) throws DatasetException {
		int datasetType = getDatasetType(datasetBytes);
		String errorReport = null;
		Dataset dataset = null;
		if (datasetType == Dataset.STREAMS) {
			dataset = getStreamingDataset(datasetBytes);
			return dataset;
		} else if (datasetType == Dataset.FILES) {
			dataset = getFileDataset(datasetBytes);
			return dataset;
		} else if (datasetType == Dataset.DATABASE) {

		}

		errorReport = "The dataset type (" + datasetType + ") is invalid.";
		throwDatasetException(errorReport);
		return dataset;
	}

	/**
	 * Creates a dataset collection
	 * 
	 * @return The created dataset collection.
	 */
	public DatasetCollection createDatasetCollection() {
		DatasetCollection datasetCollection = new DatasetCollectionManagement();
		return datasetCollection;
	}

	/**
	 * Reconstruct the dataset collection from a byte[].
	 * 
	 * @param marshalledBytes
	 *            The byte[] representation of the dataset
	 * @return The reconstructed dataset.
	 * @throws DatasetException
	 *             If the are problems reconstructing the dataset.
	 */
	public DatasetCollection getDatasetCollection(byte[] marshalledBytes)
			throws DatasetException {
		DatasetCollection datasetCollection = null;
		try {
			datasetCollection = new DatasetCollectionManagement(marshalledBytes);
		} catch (IOException ioe) {
			String errorReport = "Problems recreating DatasetCollection from marshalled bytes: "
					+ ioe.getMessage();
			throwDatasetException(errorReport);
		}
		return datasetCollection;
	}

	/**
	 * Creates a streaming dataset based on the specified arguments.
	 * 
	 * @param datasetIdentifier
	 *            The identifier for the dataset.
	 * @param datasetDescription
	 *            The description of the dataset.
	 * @return The created streaming dataset.
	 * @throws DatasetException
	 *             If there are problems creating the streaming dataset.
	 */
	public StreamingAccess createStreamingDataset(String datasetIdentifier,
			String datasetDescription) {

		StreamDataset dataset = new StreamDataset(datasetIdentifier,
				datasetDescription);

		return dataset;
	}

	/**
	 * Reconstruct the streaming dataset from a byte[] representation of it.
	 * 
	 * @param marshalledBytes
	 *            The byte[] representation of the streaming dataset.
	 * @return The reconstructed streaming dataset.
	 * @throws DatasetException
	 *             If there are problems reconstructing the streaming dataset.
	 */
	public StreamingAccess getStreamingDataset(byte[] marshalledBytes)
			throws DatasetException {
		String errorReport;
		StreamDataset dataset = null;
		try {
			dataset = new StreamDataset(marshalledBytes);

		} catch (IOException ioe) {
			errorReport = "Problems recreating Streaming Dataset "
					+ "from marshalled bytes: " + ioe.getMessage();
			throwDatasetException(errorReport);
		}
		return dataset;
	}

	/**
	 * Creates a file dataset based on the specified arguments.
	 * 
	 * @param datasetIdentifier
	 *            The identifier for the dataset.
	 * @param datasetDescription
	 *            The description of the dataset.
	 * @return The created file dataset.
	 * @throws DatasetException
	 *             If there are problems creating the file dataset.
	 */
	public FileAccess createFileDataset(String datasetIdentifier,
			String datasetDescription) {

		FileDataset dataset = new FileDataset(datasetIdentifier,
				datasetDescription);

		return dataset;
	}

	/**
	 * Reconstruct the file dataset from a byte[] representation of it.
	 * 
	 * @param marshalledBytes
	 *            The byte[] representation of the file dataset.
	 * @return The reconstructed file dataset.
	 * @throws DatasetException
	 *             If there are problems reconstructing the streaming dataset.
	 */
	public FileAccess getFileDataset(byte[] marshalledBytes)
			throws DatasetException {
		String errorReport;
		FileDataset dataset = null;
		try {
			dataset = new FileDataset(marshalledBytes);

		} catch (IOException ioe) {
			errorReport = "Problems recreating File Dataset "
					+ "from marshalled bytes: " + ioe.getMessage();
			throwDatasetException(errorReport);
		}
		return dataset;
	}

	private void throwDatasetException(String errorReport)
			throws DatasetException {
		throw new DatasetException(errorReport);
	}
}
